//
// Created by fairy on 2025/3/3 12:14.
//
#include "ui.h"
#include<zq_gui.h>
#include<math.h>
#include<zq_font.h>
#include <zq_systick.h>

#include "fft.h"
#ifdef __ARM__
#include <bits/move.h>
#endif

#ifdef SIMULATOR
#include<simulator.hpp>
zq::systick::AsyncDelay<get_tick> uiDelay;
#else
zq::systick::AsyncDelay uiDelay;
#endif


// ====================== 仿真数据 =======================
#ifdef SIMULATOR
#include <array>
#include <cmath>

// 添加自定义数学函数实现避免报错
namespace constexpr_math
{
    constexpr float pow(float x, int n)
    {
        return n == 0 ? 1.0f : x * pow(x, n - 1);
    }

    constexpr float exp(float x)
    {
        // 处理负指数
        if (x < 0) return 1.0f / exp(-x);

        // 增加泰勒展开项数到15项
        float result = 1.0f;
        float term = 1.0f;
        for (int n = 1; n < 15; ++n)
        {
            term *= x / n;
            result += term;
        }
        return result;
    }
}

constexpr std::array<float, 1024> generate_spectrum_data()
{
    std::array<float, 1024> data{};
    for (size_t i = 0; i < data.size(); ++i)
    {
        // 主频峰参数
        constexpr float peak_amplitude = 1.0f;
        constexpr float peak_width = 100.0f;
        constexpr float peak_freq = 128.0f;
        // 噪声参数
        constexpr float noise_level = 0.05f;

        // 高斯主峰
        const float gaussian = peak_amplitude *
                               constexpr_math::exp(-constexpr_math::pow((i - peak_freq) / peak_width, 2) / 2);
        // 伪随机噪声（基于索引的确定性随机）
        const float noise = noise_level *
                            (0.5f * std::sin(i * 3.14f / 180.0f) +
                             0.3f * std::cos(i * 0.78f) +
                             0.2f * std::sin(i * 2.2f));

        // 叠加信号
        data[i] = gaussian + noise;

        data[i] *= MAX_VALUE;

        // 限制幅值范围
        data[i] = data[i] < 0.0f ? 0.0f : data[i];
        data[i] = data[i] > MAX_VALUE * 1.5 ? MAX_VALUE * 1.5 : data[i];
    }
    return data;
}

constexpr std::array<float, 128> generate_square_wave_data()
{
    std::array<float, 128> data{};

    // 方波核心参数
    constexpr size_t period = 16; // 波形周期点数 采样率为Fs/2f = 128/period  128/16*2=16
    constexpr float duty_cycle = 0.5f; // 占空比 (0.0-1.0)
    constexpr float amplitude = 8000.0f; // 波形幅值
    constexpr float vertical_offset = 0.0f; // 垂直偏移

    // 派生参数计算
    constexpr size_t high_duration = static_cast<size_t>(period * duty_cycle);
    constexpr float high_value = amplitude + vertical_offset;
    constexpr float low_value = vertical_offset;

    // 生成方波数据
    for (size_t i = 0; i < data.size(); ++i)
    {
        // 计算当前点在周期内的相位
        const size_t phase = i % period;

        // 根据相位设置电平值
        data[i] = (phase < high_duration) ? high_value : low_value;

        // 可选的幅值限制（根据需求调整）
        data[i] = data[i] < 0.0f ? 0.0f : data[i];
        // data[i] = data[i] > MAX_VALUE * 1.5f ? MAX_VALUE * 1.5f : data[i];
    }

    return data;
}

constexpr auto square_wave_data = generate_square_wave_data(); // 方波数据

constexpr auto spectrum_data = generate_spectrum_data(); // 混合波
volatile uint16_t test;
// ====================== 仿真数据 =======================
#else
float square_wave_data[128];
#endif


#ifdef SIMULATOR
// std::array<float, 1024> fft_data;
#else
float fft_data[1024];
#endif


// 方波周期点数为16点，Fs/2f = N/n，也就是说方波的频率为128/16*2=Fs/16。同时基频对应的点数k= N/n=128/16=8，因此基频分量在8处
// 8 24 40 56
// 理论计算为：4*A/(PI*n)


namespace GUI
{
    static float fWaveR[FFT_SIZE], fWaveI[FFT_SIZE];
    static float w[FFT_SIZE];

    // 初始化界面
    void Render::screen()
    {
        uiDelay.start(1000);
        SpectrumDisplay::Init(); // 频谱仪初始化
        SpectrumDisplay::DrawAxes(); // 绘制坐标轴
        SpectrumDisplay::SetAmplitudeRange(0, 200); // 设置幅值范围

        // 把方波数据复制给fWaveR（兼容DSP工程）
        for (uint16_t i = 0; i < FFT_SIZE; ++i)
            fWaveR[i] = square_wave_data[i];

        std::memset(fWaveI, 0, sizeof(fWaveI)); // 清零虚部
        std::memset(w, 0, sizeof(w)); // 清零幅值表

        // 进行FFT计算
        // utils::FFT::f32<128>(fWaveR, fWaveI);
        utils::FFT::f32_128(fWaveR,fWaveI);

        // 幅值谱
        utils::FFT::f32_spectrum<128>(fWaveR, fWaveI, w);

#ifdef SIMULATOR
        printf(" FFT Magnitude Report (Symmetry Highlighted)\n");
        printf("--------------------------------------------------------------------------------\n");
        printf("| Main Freq  Mirror Freq Magnitude | Main Freq  Mirror Freq Magnitude |\n");
        printf("--------------------------------------------------------------------------------");

        // 预计算mirror_k和条件判断结果
        uint16_t mirror_k[FFT_SIZE / 2 + 1];
        bool condition_met[FFT_SIZE / 2 + 1];
        for (uint16_t k = 0; k <= FFT_SIZE / 2; k++)
        {
            mirror_k[k] = (k == 0 || k == FFT_SIZE / 2) ? k : FFT_SIZE - k;
            const bool is_peak = (k == 8 || k == 24 || k == 40 || k == 56);
            condition_met[k] = is_peak || w[k] > 0.01f;
        }

        // 第一个循环处理非零区域输出
        bool zero_block = false;
        uint16_t zero_start = 0;
        for (uint16_t k = 0; k <= FFT_SIZE / 2; k++)
        {
            if (condition_met[k])
            {
                if (zero_block)
                {
                    zero_block = false;
                }
                printf("\n|  [%3d] %7.2f  <-->  [%3d] %7.2f   |", k, w[k], mirror_k[k], w[mirror_k[k]]);
            } else
            {
                if (!zero_block)
                {
                    zero_start = k;
                    zero_block = true;
                }
            }
        }

        // 第二个循环处理零区域输出，已移除mirror_k计算
        zero_block = false;
        zero_start = 0;
        for (uint16_t k = 0; k <= FFT_SIZE / 2; k++)
        {
            if (condition_met[k])
            {
                if (zero_block)
                {
                    printf("\n|        Zero Region: [%3d-%-3d]         |", zero_start, k - 1);
                    zero_block = false;
                }
            } else
            {
                if (!zero_block)
                {
                    zero_start = k;
                    zero_block = true;
                }
            }
        }
        printf("\r\n\r\n");
#endif
    }


    void Render::draw()
    {
        // 清屏
        Tools::clear();
        SpectrumDisplay::DrawAxes();
#ifdef SIMULATOR
        if (test)
        {
            SpectrumDisplay::DrawSpectrum(w);
        } else
        {

            SpectrumDisplay::DrawSpectrum(square_wave_data.data());
        }
#else
        SpectrumDisplay::DrawSpectrum(square_wave_data);
#endif


        // 刷新
        Flag::render::set();
    }
}


// ================================== 函数实现 ==================================
namespace GUI
{
    // 静态变量定义
    int16_t SpectrumDisplay::startIndex = 0;
    int16_t SpectrumDisplay::endIndex = HALF_FFT_SIZE;
    float SpectrumDisplay::minAmpl = 0.0f;
    float SpectrumDisplay::maxAmpl = 1.0f;
}
